package com.tiger.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tiger.utils.DateTimeUtils;
import com.tiger.utils.MD5Utils;
import com.tiger.mapper.base.UserMapper;
import com.tiger.pojo.base.User;
import io.minio.GetPresignedObjectUrlArgs;
import io.minio.MinioClient;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.UUID;

/**
 * @author HuXuehao (StudiousTiger)
 * @desc 这个类的作用是
 * @date 2022/2/18
 */
@Slf4j
@RestController
public class LoginRegistrationController {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    HttpServletRequest httpServletRequest; //通过注解获取一个request

    @Autowired
    private MinioClient minioClient;

    @Value("${minio.bucketName}")
    private String bucketName;
    @Value("${info.email.url}")
    private String emailUrl;
    @Value("${info.email.refind-pwd-title}")
    private String refindPwdTitle;
    @Value("${info.email.pref2-content}")
    private String pref2Content;
    @Value("${info.email.suf2-content}")
    private String suf2Content;


    /**
     * 登录
     * @param userName
     * @param password
     * @return
     */
    @RequestMapping(value = "/loginReg/login/{userName}/{password}", name = "登录/user")
    public String login(HttpServletRequest request,@PathVariable String userName,@PathVariable String password){
        try {
            String passwordMD5 = MD5Utils.string2MD5(password);
            String userNameMD5 = MD5Utils.string2MD5(userName);
            String nowTime= DateTimeUtils.sqlDateTime2String(DateTimeUtils.currentDateTime2SQLTimestamp());

            // 找出 用户名 和 密码正确，且没有被封号的用户
            LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda();
            queryWrapper.apply("UNIX_TIMESTAMP(opt_time) <= UNIX_TIMESTAMP('" + nowTime + "')");
            queryWrapper.apply("user_name = '" + userNameMD5 + "'");
            queryWrapper.apply("user_password = '" + passwordMD5 + "'");
            List<User> users = userMapper.selectList(queryWrapper);

            if (users.size() == 1){
                httpServletRequest.getSession().setAttribute("userId",users.get(0).getUserId()); // 将id到session中
                return "true";
            } else {
                // 判断用户是否被封号
                LambdaQueryWrapper<User> queryWrapper2 = Wrappers.<User>query().lambda();
                queryWrapper2.apply("user_name = '" + userNameMD5 + "'");
                queryWrapper2.apply("user_password = '" + passwordMD5 + "'");
                List<User> users2 = userMapper.selectList(queryWrapper2);
                if (users2.size() == 1) {
                    return "noLogin";
                } else {
                    return "false";
                }
            }
        } catch (Exception e) {
            log.error(e.toString());
            return "error";
        }
    }


    /**
     * 注册
     * @param u
     * @return
     */
    @RequestMapping(value = "/loginReg/registration/{u}", name = "注册/user")
    public String registration(@PathVariable String u){
        try {
            User user = JSON.parseObject(u, User.class);
            user.setUserName(MD5Utils.string2MD5(user.getUserName())); // MD5加盐加密-用户名
            user.setUserPassword(MD5Utils.string2MD5(user.getUserPassword())); // MD5加盐加密-密码
            user.setUserEmail(MD5Utils.string2MD5(user.getUserEmail())); // MD5加盐加密-邮箱
            user.setUserCreateDate(DateTimeUtils.currentDateTime2SQLTimestamp()); // 创建时间
            user.setOptTime(DateTimeUtils.currentDateTime2SQLTimestamp()); // 封号到期时间

            // 获取默认头像
            String headPhotoURL = minioClient.getPresignedObjectUrl(
                    GetPresignedObjectUrlArgs
                            .builder()
                            .method(Method.GET)
                            .bucket(bucketName)
                            .object("1234567890.jpg")
                            .build());
            user.setUserHeadPortrait(headPhotoURL);
            int res = userMapper.insert(user);
            if (res==1){
                return "true";
            }
            return "false";
        } catch (Exception e) {
            log.error(e.toString());
            return "false";
        }
    }


    /**
     * 找回密码
     * @param email
     * @return
     */
    @Autowired
    JavaMailSenderImpl mailSender;
    @Autowired
    private JavaMailSender javaMailSender;
    @RequestMapping(value = "/loginReg/retrievePassword/{userName}/{targetEmail}", name = "找回密码/user")
    public String retrievePassword(@PathVariable String userName, @PathVariable String targetEmail){
        try {
            String userName2 = MD5Utils.string2MD5(userName);
            String targetEmail2 = MD5Utils.string2MD5(targetEmail);
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("user_name",userName2);
            wrapper.eq("user_email",targetEmail2);
            List<User> users = userMapper.selectList(wrapper);
            if (users.size()!=1){
                return "false";
            }else if (targetEmail2.equals(users.get(0).getUserEmail())){
                String from = emailUrl;
                String subject= refindPwdTitle;
                String code = UUID.randomUUID()+"";
                String content = pref2Content+ code + suf2Content;

                sendHtmlMail(from,targetEmail,subject,content);
                httpServletRequest.getSession().setAttribute("userId",users.get(0).getUserId());
                httpServletRequest.getSession().setAttribute("code",code);
                return "true";
            }
            return "false";
        } catch (MessagingException e) {
            log.error(e.toString());
            return "false";
        }
    }
    @Async  // 异步任务
    public void sendHtmlMail(String from, String targetEmail,String subject,String content) throws MessagingException {
        MimeMessage message = javaMailSender.createMimeMessage();
        MimeMessageHelper messageHelper;
        messageHelper = new MimeMessageHelper(message,true);
        messageHelper.setFrom(from);
        messageHelper.setTo(targetEmail);
        message.setSubject(subject);
        messageHelper.setText(content,true); // true表示使用HTML邮件
        javaMailSender.send(message);
    }

    /**
     * 用于重置用户名和密码
     * @param userName
     * @param password
     * @return
     */
    @RequestMapping(value = "/loginReg/resetPassword/{userName}/{password}/{code}", name = "重置用户名和密码/user")
    public String resetPassword(@PathVariable String userName,@PathVariable String password,@PathVariable String code){
        try {
            if (!code.equals(httpServletRequest.getSession().getAttribute("code"))){
                return "false";
            }
            UpdateWrapper<User> wrapper = new UpdateWrapper<>();
            wrapper.eq("user_id",(String)httpServletRequest.getSession().getAttribute("userId"));
            wrapper.set("user_name", MD5Utils.string2MD5(userName));
            wrapper.set("user_password", MD5Utils.string2MD5(password));
            int res = userMapper.update(null, wrapper);
            if (res==1){
                httpServletRequest.getSession().removeAttribute("code"); // 销毁session
                return "true";
            }else{
                return "false";
            }
        } catch (Exception e) {
            log.error(e.toString());
            return "false";
        }
    }

    /**
     * 退出登录
     * @return
     */
    @RequestMapping(value = "/loginReg/logout", name = "退出登录/user")
    public String logout(){
        try {
            httpServletRequest.getSession().removeAttribute("userId"); // 删除id
            return "true";
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
    }
}
